BUUCTF-WEB 【GWCTF 2019】枯燥的抽奖 1

考点:PHP伪随机数的破解

打开

image-20210421185959874

以为是爆破后面10位密码,用bp提交了下,发现好像回显有代码,找到后发现被隐藏了,解开得到下面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
#这不是抽奖程序的源代码!不许看!
header("Content-Type: text/html;charset=utf-8");
session_start();
if(!isset($_SESSION['seed'])){
$_SESSION['seed']=rand(0,999999999);
}

mt_srand($_SESSION['seed']);
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
# 生成20位字符串
for ( $i = 0; $i < $len1; $i++ ){
# 在 $str_long1 中 随机截取 0-61 中的一个
$str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);
}
# 显示生成的前10位
$str_show = substr($str, 0, 10);
echo "<p id='p1'>".$str_show."</p>";


if(isset($_POST['num'])){
if($_POST['num']===$str){x
echo "<p id=flag>抽奖,就是那么枯燥且无味,给你flag{xxxxxxxxx}</p>";
}
else{
echo "<p id=flag>没抽中哦,再试试吧</p>";
}
}
show_source("check.php");

这道题,在我去搜索mt_rand函数的用法的时候,搜索到一些信息。mt_rand是用来生成随机数的,但是如果mt_srand()函数的seep参数被固定后,mt_rand函数生成的随机数,就会有迹可循。

1
2
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);

这句代码的意思是 随机截取一个字符串,在$str_long1这个字符串当中,但是我们如果需要爆破的话,需要找到截取到的字符串对应的下位置,因为这个位置就是mt_rand生成的随机数。

根据对应的字符串 来生成对应的 数字

假设 这个字符串为VbjzN5cCrb

1
2
3
4
5
6
7
8
9
10
11
12
13
14

str1='abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
str2='VbjzN5cCrb'
str3 = str1[::-1]
length = len(str2)
res=''
for i in range(len(str2)):
for j in range(len(str1)):
if str2[i] == str1[j]:
res+=str(j)+' '+str(j)+' '+'0'+' '+str(len(str1)-1)+' '
break
print(res)
// 就会转换成这样
// 57 57 0 61 1 1 0 61 9 9 0 61 25 25 0 61 49 49 0 61 31 31 0 61 60 60 0 61 24 24 0 61 45 45 0 61 61 61 0 61

再用php_mt_seed工具进行爆破

1
2
3
4
5
6
7
8
9
┌──(kali㉿kali)-[~/Downloads/php_mt_seed-4.0]
└─$ ./php_mt_seed 57 57 0 61 1 1 0 61 9 9 0 61 25 25 0 61 49 49 0 61 31 31 0 61 60 60 0 61 24 24 0 61 45 45 0 61 61 61 0 61
Pattern: EXACT-FROM-62 EXACT-FROM-62 EXACT-FROM-62 EXACT-FROM-62 EXACT-FROM-62 EXACT-FROM-62 EXACT-FROM-62 EXACT-FROM-62 EXACT-FROM-62 EXACT-FROM-62
Version: 3.0.7 to 5.2.0
Found 0, trying 0xfc000000 - 0xffffffff, speed 443.2 Mseeds/s
Version: 5.2.1+
Found 0, trying 0xfe000000 - 0xffffffff, speed 21.3 Mseeds/s
Found 0
# 没跑出来

用php_mt_seed破解出来的seed值,再重新来生成完整的20位字符串。

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
# 用了个值代替
mt_srand(67413330);
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str = '';
$len1 = 20;
for ($i = 0; $i < $len1; $i++) {
# 组成规则
# 从 $str_long1 字符串中 截取
$str .= substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);
}

echo $str;

写了大致的解题过程,文本对不上,因为这个工具太不靠谱了,试了好几次,都解不出来。